package org.ljy;


import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

public class ZkClassCategory {

    public enum Category {
        SERVICE_STARTUP_AND_ENV("服务启动与环境配置"),
        CLUSTER_CONSENSUS_AND_ROLE("集群共识与角色管理"),
        REQUEST_PROCESSING_AND_TRANSACTION("请求处理与事务调度"),
        DATA_STORE_AND_SNAPSHOT("数据存储与快照管理"),
        OTHER_TRANSACTIONS("其他事务"),

        // 角色归属分类（用于标记IO操作场景下的角色关联性）
        LEADER_HAVE("仅Leader执行IO时出现"),
        FOLLOWER_HAVE("仅Follower执行IO时出现");

        private final String desc;

        Category(String desc) {
            this.desc = desc;
        }

        public String getDesc() {
            return desc;
        }
    }

    // 类名→多分类映射（按优先级排序：主要分类在前）
    private static final Map<String, List<Category>> CLASS_CATEGORY_MAP = new HashMap<>();

    static {
        // 1. 服务启动与环境配置（无跨分类）
        addSingleCategory("QuorumPeerConfig", Category.SERVICE_STARTUP_AND_ENV);
        addSingleCategory("QuorumPeerMain", Category.SERVICE_STARTUP_AND_ENV);
        addSingleCategory("Environment", Category.SERVICE_STARTUP_AND_ENV);
        addSingleCategory("ZookeeperBanner", Category.SERVICE_STARTUP_AND_ENV);
        addSingleCategory("ManagedUtil", Category.SERVICE_STARTUP_AND_ENV);
        addSingleCategory("ServerMetrics", Category.SERVICE_STARTUP_AND_ENV);
        addSingleCategory("X509Util", Category.SERVICE_STARTUP_AND_ENV);
        addSingleCategory("BlueThrottle", Category.SERVICE_STARTUP_AND_ENV);

        // 2. 集群共识与角色管理 + 跨分类
        addMultiCategory("QuorumPeer", Category.CLUSTER_CONSENSUS_AND_ROLE, Category.REQUEST_PROCESSING_AND_TRANSACTION);
        addMultiCategory("FastLeaderElection", Category.CLUSTER_CONSENSUS_AND_ROLE, Category.LEADER_HAVE);
        addMultiCategory("FastLeaderElection$Messenger$WorkerReceiver", Category.CLUSTER_CONSENSUS_AND_ROLE, Category.LEADER_HAVE);
        addMultiCategory("Leader", Category.CLUSTER_CONSENSUS_AND_ROLE, Category.REQUEST_PROCESSING_AND_TRANSACTION, Category.LEADER_HAVE);
        addMultiCategory("Follower", Category.CLUSTER_CONSENSUS_AND_ROLE, Category.REQUEST_PROCESSING_AND_TRANSACTION, Category.FOLLOWER_HAVE);
        addMultiCategory("Learner", Category.CLUSTER_CONSENSUS_AND_ROLE, Category.FOLLOWER_HAVE);
        addMultiCategory("Learner$LeaderConnector", Category.CLUSTER_CONSENSUS_AND_ROLE, Category.FOLLOWER_HAVE);
        addMultiCategory("LearnerHandler", Category.CLUSTER_CONSENSUS_AND_ROLE, Category.LEADER_HAVE);
        addMultiCategory("LearnerMaster", Category.CLUSTER_CONSENSUS_AND_ROLE, Category.LEADER_HAVE);
        addMultiCategory("LearnerSessionTracker", Category.CLUSTER_CONSENSUS_AND_ROLE, Category.FOLLOWER_HAVE);
        addMultiCategory("QuorumZooKeeperServer", Category.CLUSTER_CONSENSUS_AND_ROLE, Category.REQUEST_PROCESSING_AND_TRANSACTION);

        // 3. 请求处理与事务调度
        addSingleCategory("Server", Category.REQUEST_PROCESSING_AND_TRANSACTION);
        addSingleCategory("RequestThrottler", Category.REQUEST_PROCESSING_AND_TRANSACTION);
        addSingleCategory("PrepRequestProcessor", Category.REQUEST_PROCESSING_AND_TRANSACTION);
        addMultiCategory("ProposalRequestProcessor", Category.REQUEST_PROCESSING_AND_TRANSACTION, Category.LEADER_HAVE);
        addSingleCategory("CommitProcessor", Category.REQUEST_PROCESSING_AND_TRANSACTION);
        addSingleCategory("SyncRequestProcessor", Category.REQUEST_PROCESSING_AND_TRANSACTION);
        addSingleCategory("FinalRequestProcessor", Category.REQUEST_PROCESSING_AND_TRANSACTION);
        addMultiCategory("LeaderRequestProcessor", Category.REQUEST_PROCESSING_AND_TRANSACTION, Category.LEADER_HAVE);
        addMultiCategory("FollowerRequestProcessor", Category.REQUEST_PROCESSING_AND_TRANSACTION, Category.FOLLOWER_HAVE);
        addMultiCategory("Leader$ToBeAppliedRequestProcessor", Category.REQUEST_PROCESSING_AND_TRANSACTION, Category.LEADER_HAVE);
        addSingleCategory("FourLetterCommands", Category.REQUEST_PROCESSING_AND_TRANSACTION);
        addSingleCategory("ResponseCache", Category.REQUEST_PROCESSING_AND_TRANSACTION);
        addSingleCategory("RequestPathMetricsCollector", Category.REQUEST_PROCESSING_AND_TRANSACTION);
        // 补充ReferenceCountedACLCache的分类（请求处理与事务调度）
        addSingleCategory("ReferenceCountedACLCache", Category.REQUEST_PROCESSING_AND_TRANSACTION);

        // 4. 数据存储与快照管理
        addSingleCategory("FileTxnSnapLog", Category.DATA_STORE_AND_SNAPSHOT);
        addSingleCategory("FileTxnLog", Category.DATA_STORE_AND_SNAPSHOT);
        addSingleCategory("FileSnap", Category.DATA_STORE_AND_SNAPSHOT);
        addSingleCategory("ZKDatabase", Category.DATA_STORE_AND_SNAPSHOT);
        addSingleCategory("DataTree", Category.DATA_STORE_AND_SNAPSHOT);
        addSingleCategory("SnapStream", Category.DATA_STORE_AND_SNAPSHOT);
        addSingleCategory("DatadirCleanupManager", Category.DATA_STORE_AND_SNAPSHOT);
        addSingleCategory("ContainerManager", Category.DATA_STORE_AND_SNAPSHOT);

        // 5. 其他事务 + 跨分类
        addMultiCategory("QuorumCnxManager", Category.OTHER_TRANSACTIONS, Category.CLUSTER_CONSENSUS_AND_ROLE);
        addSingleCategory("ServerCnxnFactory", Category.OTHER_TRANSACTIONS);
        addSingleCategory("NIOServerCnxnFactory", Category.OTHER_TRANSACTIONS);
        addSingleCategory("NIOServerCnxn", Category.OTHER_TRANSACTIONS);
        addSingleCategory("AbstractConnector", Category.OTHER_TRANSACTIONS);
        addSingleCategory("QuorumCnxManager$Listener", Category.OTHER_TRANSACTIONS);
        addSingleCategory("QuorumCnxManager$Listener$ListenerHandler", Category.OTHER_TRANSACTIONS);
        addSingleCategory("DefaultSessionIdManager", Category.OTHER_TRANSACTIONS);
        addSingleCategory("SessionTrackerImpl", Category.OTHER_TRANSACTIONS);
        addMultiCategory("LeaderSessionTracker", Category.OTHER_TRANSACTIONS, Category.LEADER_HAVE);
        addSingleCategory("WatchManagerFactory", Category.OTHER_TRANSACTIONS);
        addSingleCategory("HouseKeeper", Category.OTHER_TRANSACTIONS);
        addSingleCategory("ZKAuditProvider", Category.OTHER_TRANSACTIONS);
        addSingleCategory("ContextHandler", Category.OTHER_TRANSACTIONS);
        addSingleCategory("JettyAdminServer", Category.OTHER_TRANSACTIONS);
        addSingleCategory("ZooKeeperServerListenerImpl", Category.OTHER_TRANSACTIONS);
        addSingleCategory("Log", Category.OTHER_TRANSACTIONS);

        // 单独处理ZooKeeperServer（跨2个分类）
        addMultiCategory("ZooKeeperServer", Category.REQUEST_PROCESSING_AND_TRANSACTION, Category.DATA_STORE_AND_SNAPSHOT);
    }

    // 工具方法：添加单一分类
    private static void addSingleCategory(String className, Category category) {
        List<Category> list = new ArrayList<>();
        list.add(category);
        CLASS_CATEGORY_MAP.put(className, list);
    }

    // 工具方法：添加多个分类（按优先级排序，第一个为主要分类）
    private static void addMultiCategory(String className, Category... categories) {
        List<Category> list = new ArrayList<>();
        Collections.addAll(list, categories);
        CLASS_CATEGORY_MAP.put(className, list);
    }

    // 获取类名对应的所有分类
    public static List<Category> getCategories(String className) {
        List<Category> defaultList = new ArrayList<>();
        defaultList.add(Category.OTHER_TRANSACTIONS);
        return CLASS_CATEGORY_MAP.getOrDefault(className, defaultList);
    }

    public static List<Category> determineTopTwoCategories(List<String> callStack) {
        Map<Category, Integer> weightMap = new HashMap<>();
        // 初始化权重Map（排除标识类分类）
        for (Category c : Category.values()) {
            if (c != Category.LEADER_HAVE && c != Category.FOLLOWER_HAVE) {
                weightMap.put(c, 0);
            }
        }
        // 存储标识类分类（最多一个）
        Category identifier = null;

        boolean hasKnownClass = false;
        String lastClassName = null;
        int currentWeightFactor = 1; // 栈顶初始系数为1，向下递增

        // 遍历调用栈（从栈顶到栈底）
        for (String stackElement : callStack) {
            String className = extractClassName(stackElement);
            if (className == null) continue;

            // 不同类名时系数递增（同类名不递增，避免重复计算）
            if (lastClassName != null && !className.equals(lastClassName)) {
                currentWeightFactor++;
            }

            if (CLASS_CATEGORY_MAP.containsKey(className)) {
                hasKnownClass = true;
                List<Category> categories = getCategories(className);
                for (int i = 0; i < categories.size(); i++) {
                    Category c = categories.get(i);
                    // 处理标识类分类（不参与权重计算，只记录）
                    if (c == Category.LEADER_HAVE || c == Category.FOLLOWER_HAVE) {
                        identifier = c; // 按需求不会同时出现，直接覆盖
                    } else {
                        // 普通分类计算权重（主要分类*2，次要分类*1）
                        int weight = i == 0 ? currentWeightFactor * 2 : currentWeightFactor * 1;
                        weightMap.put(c, weightMap.get(c) + weight);
                    }
                }
            }

            lastClassName = className;
        }

        // 无已知类时返回默认分类（如果有标识则附加）
        if (!hasKnownClass) {
            List<Category> defaultList = new ArrayList<>();
            defaultList.add(Category.OTHER_TRANSACTIONS);
            if (identifier != null) {
                defaultList.add(identifier);
            }
            return defaultList;
        }

        // 按权重降序排序，取前两名普通分类
        List<Category> topCategories = weightMap.entrySet().stream()
                .sorted(Map.Entry.<Category, Integer>comparingByValue().reversed())
                .filter(entry -> entry.getValue() > 0) // 过滤权重为0的分类
                .limit(2)
                .map(Map.Entry::getKey)
                .collect(Collectors.toList());

        // 如果没有有效分类（理论上不会发生，因为hasKnownClass为true）
        if (topCategories.isEmpty()) {
            topCategories.add(Category.OTHER_TRANSACTIONS);
        }

        // 附加标识类分类（如果存在）
        if (identifier != null) {
            topCategories.add(identifier);
        }

        return topCategories;
    }

    // 辅助方法：从调用栈元素中提取类名（处理内部类和方法信息）
    // 提取方法名前的类名（最后一个.与(之间的内容）
    // 提取规则：先取()内的内容，再取.之前的字符串（即文件名对应的类名）
    private static String extractClassName(String stackElement) {
        // 第一步：匹配括号中的内容（如"LearnerHandler.java:576"或"LearnerHandler.java"）
        Pattern bracketPattern = Pattern.compile("\\((.*?)\\)");
        Matcher bracketMatcher = bracketPattern.matcher(stackElement);
        if (!bracketMatcher.find()) {
            return null; // 没有括号内容，返回null
        }
        String bracketContent = bracketMatcher.group(1);

        // 第二步：取.之前的字符串（如"LearnerHandler.java" → "LearnerHandler"）
        int dotIndex = bracketContent.indexOf('.');
        if (dotIndex == -1) {
            return bracketContent; // 没有.，直接返回括号内容
        }
        return bracketContent.substring(0, dotIndex);
    }

    // 示例：测试IOPoint分类逻辑
    public static void main(String[] args) {
        // 示例调用栈（模拟包含多分类类的场景）
        List<String> callStack = Arrays.asList(
                "java.io.FileOutputStream.writeBytes$$PHOSPHORTAGGED(FileOutputStream.java)",
                "java.io.FileOutputStream.write$$PHOSPHORTAGGED(FileOutputStream.java:326)",
                "org.apache.zookeeper.common.AtomicFileOutputStream.write$$PHOSPHORTAGGED(AtomicFileOutputStream.java:72)",
                "sun.nio.cs.StreamEncoder.writeBytes$$PHOSPHORTAGGED(StreamEncoder.java:221)",
                "sun.nio.cs.StreamEncoder.implFlushBuffer$$PHOSPHORTAGGED(StreamEncoder.java:291)",
                "sun.nio.cs.StreamEncoder.implFlush$$PHOSPHORTAGGED(StreamEncoder.java:295)",
                "sun.nio.cs.StreamEncoder.flush$$PHOSPHORTAGGED(StreamEncoder.java:141)",
                "java.io.OutputStreamWriter.flush$$PHOSPHORTAGGED(OutputStreamWriter.java:229)",
                "java.io.BufferedWriter.flush$$PHOSPHORTAGGED(BufferedWriter.java:254)",
                "org.apache.zookeeper.common.AtomicFileWritingIdiom.<init>(AtomicFileWritingIdiom.java:72)",
                "org.apache.zookeeper.common.AtomicFileWritingIdiom.<init>(AtomicFileWritingIdiom.java:54)",
                "org.apache.zookeeper.server.quorum.QuorumPeer.writeLongToFile$$PHOSPHORTAGGED(QuorumPeer.java:2139)",
                "org.apache.zookeeper.server.quorum.QuorumPeer.setCurrentEpoch$$PHOSPHORTAGGED(QuorumPeer.java:2162)",
                "org.apache.zookeeper.server.quorum.Learner.syncWithLeader$$PHOSPHORTAGGED(Learner.java:732)",
                "org.apache.zookeeper.server.quorum.Follower.followLeader$$PHOSPHORTAGGED(Follower.java:107)",
                "org.apache.zookeeper.server.quorum.QuorumPeer.run$$PHOSPHORTAGGED(QuorumPeer.java:1467)",
                "org.apache.zookeeper.server.quorum.QuorumPeer.run(QuorumPeer.java:0)"
        );        // 集群共识（主要）、请求处理（次要）

        List<Category> ioCategory = determineTopTwoCategories(callStack);
        for(Category ioC: ioCategory){
            System.out.println("IOPoint所属分类：" + ioC.getDesc());
        }

        // 权重计算：
        // 集群共识：LearnerHandler(2) + QuorumPeer(2) = 4
        // 请求处理：ZooKeeperServer(2) + QuorumPeer(1) = 3
        // 数据存储：ZooKeeperServer(1) = 1
        // 输出：集群共识与角色管理
    }
}